package io.gitee.zhangbinhub.admin.controller.openinner

import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.admin.api.CommonPath
import io.gitee.zhangbinhub.admin.api.WorkFlowApi
import io.gitee.zhangbinhub.admin.base.BaseController
import io.gitee.zhangbinhub.admin.po.ProcessHandlingPo
import io.gitee.zhangbinhub.admin.po.ProcessStartPo
import io.gitee.zhangbinhub.admin.po.ProcessTerminationPo
import io.gitee.zhangbinhub.admin.service.WorkFlowService
import io.gitee.zhangbinhub.admin.vo.InfoVo
import io.gitee.zhangbinhub.admin.vo.ProcessInstanceVo
import io.gitee.zhangbinhub.admin.vo.ProcessTaskVo
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.noear.solon.annotation.Body
import org.noear.solon.annotation.Controller
import org.noear.solon.annotation.Mapping
import org.noear.solon.annotation.Path
import org.noear.solon.core.handle.MethodType
import org.noear.solon.core.util.MimeType
import org.noear.solon.validation.annotation.Valid
import org.noear.solon.validation.annotation.Validated

@Valid
@Controller
@Api("工作流引擎（内部开放接口）")
open class OpenInnerWorkFlowController(
    private val logAdapter: LogAdapter,
    private val workFlowService: WorkFlowService
) : BaseController(logAdapter) {
    @ApiOperation("获取流程任务信息", notes = "获取指定流程任务")
    @Mapping(
        method = [MethodType.GET],
        value = "${CommonPath.openInnerBasePath}${WorkFlowApi.workFlow}" + WorkFlowApi.task + "/{taskId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun queryTaskInfo(
        @ApiParam("流程任务ID", required = true)
        @Path(name = "taskId") taskId: Long
    ): ProcessTaskVo = workFlowService.findTaskByIdOpen(taskId)

    @ApiOperation("启动流程", notes = "启动指定的流程，并关联唯一业务主键")
    @Mapping(
        method = [MethodType.PUT],
        value = "${CommonPath.openInnerBasePath}${WorkFlowApi.workFlow}" + WorkFlowApi.start,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun start(@Body @Validated processStartPo: ProcessStartPo): InfoVo =
        InfoVo(message = workFlowService.startFlow(processStartPo).id.toString())

    @ApiOperation("启动流程", notes = "启动指定的流程，并关联唯一业务主键")
    @Mapping(
        method = [MethodType.PUT],
        value = "${CommonPath.openInnerBasePath}${WorkFlowApi.workFlow}" + WorkFlowApi.start + "/{userId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun startByUser(
        @Path(name = "userId") userId: String,
        @Body @Validated processStartPo: ProcessStartPo
    ): InfoVo = InfoVo(message = workFlowService.startFlow(processStartPo, userId).id.toString())

    @ApiOperation("流程处理", notes = "可选通过或不通过")
    @Mapping(
        method = [MethodType.POST],
        value = "${CommonPath.openInnerBasePath}${WorkFlowApi.workFlow}" + WorkFlowApi.process + "/{userId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun processByUser(
        @Path(name = "userId") userId: String,
        @Body @Validated processHandlingPo: ProcessHandlingPo
    ): InfoVo = workFlowService.skip(processHandlingPo, userId).let {
        InfoVo(message = "流程处理完成")
    }

    @ApiOperation("查询待办任务")
    @Mapping(
        method = [MethodType.GET],
        value = "${CommonPath.openInnerBasePath}${WorkFlowApi.workFlow}" + WorkFlowApi.pending + "/{processInstanceId}/{userId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun pendingByUser(
        @Path(name = "processInstanceId") processInstanceId: Long,
        @Path(name = "userId") userId: String
    ): List<ProcessTaskVo> = workFlowService.findTaskList(processInstanceId, userId)

    @ApiOperation("流程强制结束")
    @Mapping(
        method = [MethodType.DELETE],
        value = "${CommonPath.openInnerBasePath}${WorkFlowApi.workFlow}" + WorkFlowApi.termination,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun termination(@Body @Validated processTerminationPo: ProcessTerminationPo): InfoVo =
        workFlowService.findProcessInstance(processTerminationPo.processInstanceId!!).let { instance ->
            if (instance.finished) {
                logAdapter.warn("流程已结束，无法再次终止该流程！")
            }
            workFlowService.terminationFlow(processTerminationPo).let {
                InfoVo(message = "强制结束流程实例成功")
            }
        }

    @ApiOperation("获取流程实例", notes = "获取指定流程实例")
    @Mapping(
        method = [MethodType.GET],
        value = "${CommonPath.openInnerBasePath}${WorkFlowApi.workFlow}" + WorkFlowApi.instance + "/{processInstanceId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun queryInstance(
        @ApiParam("流程实例id", required = true)
        @Path(name = "processInstanceId")
        processInstanceId: Long
    ): ProcessInstanceVo = workFlowService.findProcessInstance(processInstanceId)
}
